package love.contact;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import wwk.common.constant.Commonstant;
import wwk.common.event.MessageManager;
import wwk.common.util.DateTimeUtil;
import wwk.common.util.FileUtil;
import wwk.common.util.SysUtil;
import wwk.common.util.ZipUtil;
import wwk.common.widget.CustomDialog;
import wwk.common.widget.NavigationBar;
import love.contact.adapter.FileListAdapter;
import love.contact.data.ContactConst;
import love.contact.data.PhoneBook;
import love.contact.engine.ContactIconOperateDelegate;
import love.contact.engine.Engine;
import love.contact.engine.TheApplication;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

public class ImExportActivity extends BaseActivity implements OnItemClickListener{

	private ListView listView;
	private String exportsParentPath;
	private String exportsPath;
	private String tempPath;
	
	final static private String EXT=".ctt";
	final static private String ContactsFileName="contacts";
	final static private String IconsFileName="icons";
	final static private String ExportsDirName="exports";
	final static private String TempDirName="temp";
	
	private FileListAdapter listViewAdapter;
	private ProgressDialog progressDialog;
	private Handler handler = new Handler() 
	{
		@Override
		public void handleMessage(Message msg) 
		{
			super.handleMessage(msg);
			
			switch(msg.what)
			{
				case ContactConst.MSG_IMPORT_INIT:
					{
						 int count=msg.arg1;
						 progressDialog.setProgress(0);
						 progressDialog.setMax(count);
						 progressDialog.setMessage(getString(R.string.importing));
					}
					break;
				case ContactConst.MSG_IMPORT_INCREASE:
					{
						int max=progressDialog.getMax();
						int cur=progressDialog.getProgress();
						if(cur+1<=max)
						{
							progressDialog.setProgress(cur+1);
						}
					}
					break;
				case ContactConst.MSG_IMPORT_FINISH:
					{
						progressDialog.hide();
						progressDialog=null;
						Toast.makeText(ImExportActivity.this,R.string.importFinish, Toast.LENGTH_SHORT).show();
						
						TheApplication theApp=(TheApplication)getApplication();
					    theApp.engine.resetCurrentGroup();
					    
					    MessageManager.instance().sendMessage(Commonstant.Message_Contact_Changed);
					    
						//Intent intent=new Intent(ImExportActivity.this,MainTabActivity.class);
			 			//startActivity(intent);
			 			
			 			//ImExportActivity.this.finish();
					}
					break;
				case ContactConst.MSG_IMPORT_FAIL:
					{
						progressDialog.hide();
						progressDialog=null;
						Toast.makeText(ImExportActivity.this,R.string.importFail, Toast.LENGTH_SHORT).show();
					}
					break;
				case ContactConst.MSG_EXPORT_INIT:
					{
						 int count=msg.arg1;
						 progressDialog.setProgress(0);
						 progressDialog.setMax(count);
						 progressDialog.setMessage(getString(R.string.exporting));
					}
					break;
				case ContactConst.MSG_EXPORT_INCREASE:
					{
						int max=progressDialog.getMax();
						int cur=progressDialog.getProgress();
						if(cur+1<=max)
						{
							progressDialog.setProgress(cur+1);
						}
					}
					break;
				case ContactConst.MSG_EXPORT_FINISH:
					{
						progressDialog.hide();
						progressDialog=null;
						Toast.makeText(ImExportActivity.this,R.string.exportFinish, Toast.LENGTH_SHORT).show();
						
						listViewAdapter.refresh();
						listViewAdapter.notifyDataSetChanged();
					}
					break;
				case ContactConst.MSG_REMOVAL_FINISH:
					{
						listViewAdapter.refresh();
						listViewAdapter.notifyDataSetChanged();
					}
					break;
			}
		}
	};
	
	@Override
	public void onStart()
	{
		super.onStart();

        String sdCard=FileUtil.getSdCardDir();
        if(sdCard!=null)
        {
        	exportsParentPath=sdCard+File.separator+SysUtil.getPackageName(this)+File.separator;
        	exportsPath=exportsParentPath+ExportsDirName+File.separator;
        	tempPath=exportsParentPath+TempDirName+File.separator;
        	FileUtil.createPath(exportsPath);
        	FileUtil.createPath(tempPath);
        }
        
        this.setContentView(R.layout.common_nav_list_activity);
        
        NavigationBar navigationBar=(NavigationBar)this.findViewById(R.id.navBar);
		
		View rButton=(View)navigationBar.addRightButton(R.layout.export_button);
        rButton.setOnClickListener(new OnClickListener()
        {
			@Override
			public void onClick(View arg0) {
				onExport();
			}
        	
        });
        
		String title=this.getString(R.string.imExport);
        setTitle(title);
        navigationBar.setTitle(title);

		listView=(ListView)this.findViewById(android.R.id.list);
		listView.setCacheColorHint(0);
		Drawable color=new ColorDrawable(0xFF000000);
		listView.setDivider(color);
		listView.setDividerHeight(1);
		listView.setTextFilterEnabled(true);
		
		registerForContextMenu(listView);  

		//adapter
		listViewAdapter=new FileListAdapter(this,exportsPath);
		listView.setAdapter(listViewAdapter);
		
		//listener
		listView.setOnItemClickListener(this);

		//empty view
		TextView emptyView=(TextView)findViewById(android.R.id.empty);
		emptyView.setText(R.string.emptyExports);
		listView.setEmptyView(emptyView); 
		
		if(exportsParentPath!=null)
		{
			Runnable r=new Runnable(){
				@Override
				public void run() {
					removalVersion1BackupFiles();
					handler.sendEmptyMessage(ContactConst.MSG_REMOVAL_FINISH);
				}
			};
			new Thread(r).start();
		}
    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) 
	{		
		MenuItem menuItem=menu.add(0,0,0,R.string.exportContacts);
		menuItem.setIcon(R.drawable.ic_export);
	
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public void onResume() 
	{
		super.onResume();

		final TheApplication theApp=(TheApplication)getApplication();
	    if(theApp.engine.pendingFilePathName!=null)
	    {
	    	new Handler().postDelayed(new Runnable()
	    	{
	    	    public void run() 
	    	    {
		    	    	File file=new File(theApp.engine.pendingFilePathName);
		    	    	checkImportFile(file);
		    	    	
		    	    	theApp.engine.pendingFilePathName=null;
	    	    }
	    	 }, 100);
	    }
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		if(!FileUtil.isSdCardExists())
		{
			CustomDialog.showInfoDialog(this,getString(R.string.sdNoExists), android.R.drawable.ic_menu_info_details, null);
			return super.onOptionsItemSelected(item);
		}
		
		onExport();
		
		return super.onOptionsItemSelected(item);
	}

	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
	{
		super.onCreateContextMenu(menu, v, menuInfo);

		AdapterView.AdapterContextMenuInfo adapterContextMenuInfo =(AdapterView.AdapterContextMenuInfo)menuInfo;
	    int position=adapterContextMenuInfo.position;
	    File file=listViewAdapter.getFile(position);
	    
		menu.setHeaderTitle(file.getName());
		menu.setHeaderIcon(R.drawable.ic_file);
		menu.add(0, 0, 0,R.string.fileInfo); 
		menu.add(0, 1, 0,R.string.toImport);  
		menu.add(0, 2, 0,R.string.toDelete);  
		menu.add(0, 3, 0, R.string.share);  
	}
	
	public boolean onContextItemSelected(MenuItem item)
	{
		 AdapterView.AdapterContextMenuInfo menuInfo =(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
	     int position=menuInfo.position;

	     int itemId=item.getItemId();
		 switch(itemId)
		 {
		 	 case 0:
				 {
					 showFileInfo(position);
				 }
				 break;
			 case 1:
			 	{
			 		File file=listViewAdapter.getFile(position);
			 		checkImportFile(file);
			 	}
			 	break;
			 case 2:
			 	{
			 		boolean ret=CustomDialog.showSelectDialog(this,getString(R.string.confirmDelete));
			 		if(ret)
			 		{
				 		File file=listViewAdapter.getFile(position);
				 		FileUtil.delete(file);

				 		listViewAdapter.refresh();
						listViewAdapter.notifyDataSetChanged();
			 		}
			 	}
			 	break;
		 	case 3:
		 		{		 		
		 			ArrayList<Uri> uriArray = new ArrayList<Uri>();

		 			String mime="text/html";
		 			File file=listViewAdapter.getFile(position);
		 			if(file.isDirectory())
		 			{
		 				ArrayList<File> fileArray=new ArrayList<File>();
					    //fileArray.add(file);

		 				File files[] = file.listFiles(); 
					    for(int i=0;i<files.length;i++)
					    { 
					    	//String contactFilePathName="file://"+files[i].getPath();
				 			//uriArray.add(Uri.parse(contactFilePathName));
					    	
					    	fileArray.add(files[i]);
					    } 
		 				
					    File zipFile=new File(exportsParentPath+file.getName()+".ctt");
					    zipFile.delete();
					    try 
					    {
							zipFile.createNewFile();
							
							ZipUtil.zipFiles(fileArray, zipFile, file.getName());
							
							String contactFilePathName="file://"+zipFile.getPath();
				 			uriArray.add(Uri.parse(contactFilePathName));
				 			mime="application/zip";
						} 
					    catch (IOException e1) 
					    {
							e1.printStackTrace();
						}
		 			}
		 			else
		 			{
		 				String contactFilePathName="file://"+file.getPath();
			 			uriArray.add(Uri.parse(contactFilePathName));
		 			}
		 			
		 			if(uriArray.size()>0)
		 			{
						boolean multiple = uriArray.size() > 1;
			            Intent intent = new Intent(multiple ? android.content.Intent.ACTION_SEND_MULTIPLE : android.content.Intent.ACTION_SEND);
			            if (multiple) 
			            {
			                intent.setType("*/*");
			                intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriArray);
			            } 
			            else
			            {
			            	intent.setType(mime);
			                intent.putExtra(Intent.EXTRA_STREAM, uriArray.get(0));
			            }
					    startActivity(Intent.createChooser(intent,getString(R.string.share)));
		 			}
				}
				break;
		 }
		
		 return super.onContextItemSelected(item);
	}
	
	private void removalVersion1BackupFiles()
	{
		//backup dir
		String oldBackupPath=exportsParentPath+"backup"+File.separator;
		File backupDir=new File(oldBackupPath);
		if(!backupDir.exists())
		{
			return;
		}
		
		File[] fileArray=backupDir.listFiles();
		int count=fileArray.length;
		for(int i=0;i<count;i++)
		{
			File subFile=fileArray[i];

	 		if(subFile.isDirectory())
	 		{
	 			File contactFile=null;
	 			File iconFile=null;
	 			
	 			File files[] = subFile.listFiles(); 
			    for(int j=0;j<files.length;j++)
			    { 
				    	if(j==0)
				    	{
				    		contactFile=files[0];
				    	}
				    	else if(j==1)
				    	{
				    		iconFile=files[1];
				    	}
			    	
				    	if(files[j].getName().equals(ContactsFileName))
				    	{
				    		contactFile=files[j];
				    	}
				    	else if(files[j].getName().equals(IconsFileName))
				    	{
				    		iconFile=files[j];
				    	}
			    } 

				String zipPathFileName=exportsPath+subFile.getName()+EXT;
				if(!FileUtil.isFileExists(zipPathFileName))
				{
					saveZipFile(zipPathFileName,contactFile,iconFile);
				}
				
				for(int j=0;j<files.length;j++)
			    { 
				    	files[j].delete();
			    } 	 		    
	 		}//end dir
	 		
	 		subFile.delete();
		}//end for
 		
		backupDir.delete();

		//love.contact zips
		
		
	}
	
	static public void saveZipFile(String zipFilePathName,File contactFile,File iconFile)
	{
		ArrayList<File> fileArray=new ArrayList<File>();
		if(contactFile!=null && contactFile.exists())
		{
			fileArray.add(contactFile);
		}
		if(iconFile!=null && iconFile.exists())
		{
			fileArray.add(iconFile);
		}
		if(fileArray.size()==0)
		{
			return;
		}
		
	    File zipFile=new File(zipFilePathName);
	    zipFile.delete();
	    try 
	    {
			zipFile.createNewFile();
			ZipUtil.zipFiles(fileArray, zipFile, "");
		} 
	    catch (IOException e1) 
	    {
			e1.printStackTrace();
		}
	}
	
	private void checkImportFile(File file)
	{
		ZipInputStream zipInputStream=null;
 		InputStream contactFileInputStream=null;
 		InputStream iconFileInputStream=null;

 		if(file.getName().endsWith(".zip") || file.getName().endsWith(EXT))
		{
			try
			{
				ZipFile zf = new ZipFile(file);
				InputStream in = new BufferedInputStream(new FileInputStream(file));
				zipInputStream = new ZipInputStream(in);
				ZipEntry ze;
				
				int i=0;
				while ((ze = zipInputStream.getNextEntry()) != null) 
				{
					if (!ze.isDirectory())  
					{
				    	if(ze.getName().equals(ContactsFileName))
				    	{
				    		contactFileInputStream=zf.getInputStream(ze);
				    	}
				    	else if(ze.getName().equals(IconsFileName))
				    	{
				    		iconFileInputStream=zf.getInputStream(ze);
				    	}
					}
					
					i++;
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}

 		if(contactFileInputStream!=null)
 		{
 			onImport(zipInputStream,contactFileInputStream,iconFileInputStream);
 		}
 		else
 		{
 			Toast.makeText(this,R.string.fileParseFail, Toast.LENGTH_SHORT).show();
 		}
	}
	
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,long id) 
	{
		showFileInfo(position);
	}
	
	private void showFileInfo(int position)
	{
	 	File file=listViewAdapter.getFile(position);
	 	String filePathName=file.getPath();
	 	InputStream inputStream=null;
	 	
	 	if(file.getName().endsWith(".zip") || file.getName().endsWith(EXT))
	 	{
	 		try
			{
				ZipFile zf = new ZipFile(file);
				InputStream in = new BufferedInputStream(new FileInputStream(file));
				ZipInputStream zin = new ZipInputStream(in);
				ZipEntry ze;
				
				int i=0;
				while ((ze = zin.getNextEntry()) != null) 
				{
					if (!ze.isDirectory())  
					{
						if(i==0)
				    	{
							inputStream=zf.getInputStream(ze);
				    	}
				    	
				    	if(ze.getName().equals(ContactsFileName))
				    	{
				    		inputStream=zf.getInputStream(ze);
				    	}
					}
					
					i++;
				}
				zin.closeEntry();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
	 	}
 		else
 		{
 			inputStream=FileUtil.getInputStream(file);
 		}
	 	
	 	String info=PhoneBook.getImportFileInfo(this,inputStream,filePathName);
	 		
	 	CustomDialog.showInfoDialog(this,getString(R.string.fileInfo),R.drawable.ic_about,info);
	}
	
	private void onImport(ZipInputStream zipInputStream,InputStream contactFileInputStream,InputStream iconFileInputStream)
	{
		 boolean ret=CustomDialog.showSelectDialog(this,getString(R.string.confirmImport),getString(R.string.confirmImportDesc));
		 if(ret)
		 {				
			 progressDialog=new ProgressDialog(ImExportActivity.this);
			 progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			 progressDialog.setMessage(getString(R.string.importing));
			 progressDialog.setIcon(null);
			 progressDialog.setIndeterminate(false);
			 progressDialog.setCancelable(false);
			 progressDialog.show();
			 progressDialog.setProgress(0);
			 progressDialog.setMax(0);
			 progressDialog.incrementProgressBy(0);
			 
			ImportThread importThread=new ImportThread();
			importThread.zipInputStream=zipInputStream;
			importThread.contactFileInputStream=contactFileInputStream;
			importThread.iconFileInputStream=iconFileInputStream;
			importThread.context=this;
			importThread.handler=handler;
			TheApplication theApp=(TheApplication)getApplication();
			importThread.engine=theApp.engine;
			importThread.start();
		 }
	}

	private void testExportVCard()
	{
		try 
		{
			ContentResolver cr = getContentResolver();
			Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
			int index = cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY); 
			
			FileOutputStream fout = new FileOutputStream("/sdcard/00tt.vcf");

			byte[] data = new byte[1024 * 1];
			while(cur.moveToNext())
			{
				String lookupKey = cur.getString(index);
				Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
				AssetFileDescriptor fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
				FileInputStream fin = fd.createInputStream();
				int len = -1;
				while((len = fin.read(data)) != -1)
				{
					fout.write(data, 0, len);
				}
				fin.close();
			}
			fout.close();
		}
		catch (FileNotFoundException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void onExport()
	{
		StringBuffer zipFileNameBuffer=new StringBuffer();
		zipFileNameBuffer.append(DateTimeUtil.getNow14());
		
		boolean ret=CustomDialog.showQueryDialog(this,getString(R.string.enterExportName), R.drawable.ic_export, zipFileNameBuffer);
		if(!ret || zipFileNameBuffer.length()==0)
		{
			return;
		}

		zipFileNameBuffer.append(EXT);
		final String zipPathFileName=exportsPath+zipFileNameBuffer;
		if(FileUtil.isFileExists(zipPathFileName))
		{
			CustomDialog.showAlertDialog(this,getString(R.string.fileExists));
			return;
		}
		
		String contactFilePathName=tempPath+ContactsFileName;
		String iconFilePathName=tempPath+IconsFileName;
		FileUtil.delete(contactFilePathName);
		FileUtil.delete(iconFilePathName);
		
		 progressDialog=new ProgressDialog(ImExportActivity.this);
		 progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		 progressDialog.setMessage(getString(R.string.exporting));
		 progressDialog.setIcon(null);
		 progressDialog.setIndeterminate(false);
		 progressDialog.setCancelable(false);
		 progressDialog.setProgress(0);
		 progressDialog.setMax(0);
		 progressDialog.incrementProgressBy(0);

		ExportThread exportThread=new ExportThread();
		exportThread.zipFilePathName=zipPathFileName;
		exportThread.contactFilePathName=contactFilePathName;
		exportThread.iconFilePathName=iconFilePathName;
		exportThread.context=this;
		exportThread.handler=handler;
		TheApplication theApp=(TheApplication)getApplication();
		exportThread.engine=theApp.engine;
		exportThread.start();
		
		handler.postDelayed(new Runnable()
		{
			public void run() 
	    	    {
				 progressDialog.show();
	    	    }
		}, 1000);
	}
}

class ImportThread extends Thread implements ContactIconOperateDelegate
{
	public ZipInputStream zipInputStream;
	public InputStream contactFileInputStream;
	public InputStream iconFileInputStream;
	public Context context;
	public Handler handler;
	public Engine engine;
	
	public void run()
	{
		boolean ret=engine.getPhoneBook().importe(context,contactFileInputStream,iconFileInputStream,handler);
		if(ret)
		{
			try 
			{
				Thread.sleep(1000);
			} 
			catch (InterruptedException e) 
			{
				e.printStackTrace();
			}
			
			handler.sendEmptyMessage(ContactConst.MSG_IMPORT_FINISH);
		}
		else
		{
			handler.sendEmptyMessage(ContactConst.MSG_IMPORT_FAIL);
		}
		
		if(zipInputStream!=null)
		{
			try 
			{
				zipInputStream.closeEntry();
			} 
			catch (IOException e) 
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@Override
	public long appendIconBytes(byte[] iconBytes) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public byte[] getIconBytes(int start, int length) {
		return null;
	}
}

class ExportThread extends Thread implements ContactIconOperateDelegate
{
	public String zipFilePathName;
	public String contactFilePathName;
	public String iconFilePathName;
	public Context context;
	public Handler handler;
	public Engine engine;
	
	public void run()
	{
		String fileContent=engine.getPhoneBook().export(context,handler,this);
		
		try 
		{
			Thread.sleep(1000);
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		
		//save
		byte[] bytes=null;
		try 
		{
			bytes = fileContent.getBytes("utf8");
			if(bytes!=null)
			{
				FileUtil.write(contactFilePathName, bytes, bytes.length, false);
			}
		} 
		catch (UnsupportedEncodingException e) 
		{
			e.printStackTrace();
		}
	    
	    ImExportActivity.saveZipFile(zipFilePathName,new File(contactFilePathName),new File(iconFilePathName));
		
		handler.sendEmptyMessage(ContactConst.MSG_EXPORT_FINISH);
	}

	@Override
	public long appendIconBytes(byte[] iconBytes) {
		long fileSize=-1;
		if(iconBytes!=null)
		{
			long size=FileUtil.write(iconFilePathName, iconBytes, iconBytes.length, true);
			if(size>0)
			{
				fileSize=FileUtil.getFileLength(iconFilePathName);
			}
		}

		return fileSize;
	}

	@Override
	public byte[] getIconBytes(int start, int length) {
		// TODO Auto-generated method stub
		return null;
	}
}
